/*
    Copyright (c) 1991, 1992 by the MIT Media Laboratory
    
    This software is distributed by Michael Hawley of the MIT Media Laboratory. 
    We hope it will be useful to you.
    
    Permission to use, copy, or modify this software for educational 
    and research purposes only and without fee is hereby granted 
    provided this notice appears on all copies, and provided you send 
    us your improvements.  Any other use of this software, in original 
    or modified form, in whole or in part, requires specific permission 
    from MIT.  This software shall not be used, rewritten, or adapted 
    for use in a commercial product without first obtaining appropriate 
    licenses from MIT.  MIT makes no representations about the suitability 
    of this software for any purpose: it is provided "as is" without any 
    warranty and any risk, damage, or liability incurred through your use 
    of this software is yours alone.
    
    Michael Hawley
    MIT Media Laboratory
    20 Ames Street, 
    Cambridge, MA 02139
    mike@media-lab.mit.edu
*/
/*
 *
 * Implement the License & info panels, receipt mechanism, and Suggestion box.
 *
 * The License declares the Media Laboratory copyright with an
 * enjoinder to prevent people from re-selling the software,
 * but a hearty encouragement to urge folks to modify and improve
 * the code -- providing the improvements are sent back to us
 * and the license remains intact.  The License also exempts the
 * Media Lab from any blame due to any damage incurred by users.
 *
 * Acceptance of the License (by first-time users) sends a receipt
 * (akin to a "read receipt" in Mail) back to the home base,
 * to maintain a census of the population using the code.
 *
 * Note that the first time this was tried without mention of the
 * outgoing receipt, many reacted badly to the implication that
 * software might act "behind their back."  But an acknowledged
 * receipt should not be problematic, and it is not unreasonable
 * for the author to want to understand the user community.
 *
 * The other feedback channel here is the -suggestion: method,
 * which composes an e-mail letter so user's comments, bugs, and
 * improvements can be collected.
 *
 *    IMPORTANT: #define ReceiptsTo and CommentsTo, below, and prepare
 *        the receiving mailboxes.
 *    
 *
 * Michael Hawley
 * mike@media-lab.mit.edu
 */

#import "Defaults.h"
#import "License.h"
#import "ColorBars.h"
#import "ColorScroller.h"

@implementation License

        /* NULL or "" will disable receipt mechanism */
#define ReceiptsTo	"receipts@tome.media.mit.edu"
#define CommentsTo	"comments@tome.media.mit.edu"

#define AppName [NXApp appName]
extern char *Version();

static char *local_stripnl(char *s){ /* remove trailing space */
    char *p;
    for (p=s;*p;p++) if (*p == '\n' || *p == '\r') *p = '\0';
    return s;
}

char *
execstr(char *s) { /* replace contents of 's' with piped output */
    FILE *f = popen(s,"r");
    char *p = s;
    *s = '\0';
    if (f){
        while (fgets(p,256,f))
            local_stripnl(p), p += strlen(p);
        pclose(f);
    }
    return s;
}

- windowWillClose:sender {
    [infobars stopIt];
    return self;
}

static id _version;

char *
Version(void){
    char *s = (char *)[_version stringValue];
    return s? s : "1.0";
}

int
FirstUse(void){ // true if this is the first time the app's been used
    return (*FirstUsed)? 0 : 1;
}

void
mailReceipt(char *subj, char *body, char *to)
/*
 * Send a read/run receipt form to "ReceiptsTo" address,
 * to indicate that the user has accepted the License.
 * If "to" and "ReceiptsTo" are blank (or NULL), this is a no-op.
 */
{
    char s[1024], u[256]="whoami", m[256]="hostname", t[4096], tmp[128];
    FILE *f;

    if (!to || !*to)     to   = ReceiptsTo;
    if (!to || !*to)     return;
    if (!subj || !*subj) subj = (char *)AppName;
    execstr(u); execstr(m);
    if (!body || !*body){
        body = t;
        sprintf(body, "\nIf this receipt bounces back to you,\n\
could you please correct the address if possible,\n\
and aim it to: %s\n\
to let us know you're registered.\n",ReceiptsTo);
    }
    strcpy(tmp,"/tmp/openerXXXXXX"); mktemp(tmp);
    if (f = fopen(tmp,"w")){
        fprintf(f,"%s",body);
        fclose(f);
        sprintf(s,"(/usr/ucb/Mail -s \"%s %s@%s\" %s < %s; rm %s) &",
                subj,u,m,to,tmp,tmp);
        system(s);
    }
}

- suggestion:sender {
    char subj[256], w[256] = "whoami";
    char body[4096]="\
Michael:\n\n\
Wow!  Sure beats watching the Weather Channel on cable!\n\
What can I possibly do to express my gratitude?\n\n\
I understand you have a spastic Media Lab 8-man crew team\n\
that desperately needs funding for a new shell.\n\
Word is, you don't even have money for uniforms\n\
and have been rowing in the nude; this will not be a pretty sight at Henley.\n\
I'm sure I can cough up a few bucks, at least enough\n\
to help you keep the cox covered (tax-deductible contributions may\n\
be sent to Crewmeister Bob Green, c/o MIT Media Lab, 20 Ames Street,\n\
Cambridge, MA 02139).\n\n\
Meanwhile, you will doubtless appreciate hearing about the following problem:\n\n\
   <insert irritating bug here>\n\n\
             rebarbitively,\n\
             ";
#define fcall(a)  [s performRemoteMethod:a]
#define call(a,b) [s performRemoteMethod:a with:b length:strlen(b)+1]
    id s = [NXApp appSpeaker];
    extern NXPortFromName();

    NXPortFromName("Mail", NULL); // make sure app is launched
    [s setSendPort:NXPortFromName("MailSendDemo", NULL)];

    sprintf(subj,"Comments and suggestions for ``%s'' %s",AppName,Version());
    sprintf(body+strlen(body),"%s\n",execstr(w));
    call("setTo:",CommentsTo);
    call("setSubject:",subj);
    call("setBody:",body);
    
    return self;
}

static int init = 0;

- setScrollview:t { // staple in a ColorScroller
    id s;
    NXRect r;
    NXColor paleYellow = NXConvertRGBToColor(1.0, 238./256., 200./256.);
    scrollview = t;
    [[t vertScroller] getFrame:&r];
    s = [[ColorScroller alloc] initFrame:&r];
    [t setVertScroller:s];
    t = [t docView];
    [t setBackgroundColor:paleYellow];
    // fix scrollbar thumb
    [t setSel:0:0];
    [t replaceSel:"\n"];
    [t setEditable:NO];
    return self;
}

- (void) load {
    if (!init){
        init++, [NXApp loadNibSection:"License.nib" owner:self];
	_version = version;
	[infobars setBackgroundColor:NX_COLORLTGRAY];
	[infobars setDrawstyle:CLEAR];
	[infopanel setDelegate:self];
        [panel setBackgroundGray:1.];
        if (!FirstUse()){ // already registered, so rearrange the panel
            init++;
	    [quit setIcon:"registered"];
	    [quit setBordered:NO];
	    [quit setEnabled:NO];
	    [quit sizeToFit];
	    [quit moveBy:-32.:-8.];
	    [accept setTitle:"Okay"];
        }
    }
}

- show:sender {
    [self load];
    [colorbars setDrawstyle:CLEAR];
    [panel makeKeyAndOrderFront:sender];
    [colorbars setDrawstyle:SWAB];
    [NXApp runModalFor:panel];
    return self;
}

- info:sender {
    [self load];
    [infobars setDrawstyle:CLEAR];
    [infopanel makeKeyAndOrderFront:sender];
    [infobars setDrawstyle:SWAB];
    return self;
}

- sendReceipt { // send a receipt to indicate the user has read the license
    char *ctime(), s[1024];
    long time(), t = time(0);

    sprintf(s,"%s-%s-registered",AppName,Version());
    if (t < 793414430 /* 1995 */) mailReceipt(s,0,ReceiptsTo);
    strcpy(FirstUsed,ctime(&t));
    local_stripnl(FirstUsed);
    writeDefaults();
    return self;
}

- accept:sender {
    if (init < 2){ // accept the license: rearrange panel & send receipt
	id s = [Sound findSoundFor:"Stamp"];
        init++;
	[panel disableFlushWindow];
        [quit setIcon:"registered"];
        [quit setBordered:NO];
        [quit setEnabled:NO];
        [quit sizeToFit];
	[quit setTransparent:YES];
        [quit moveBy:-32.:-8.];
        [accept setTitle:"Okay"];
	[panel display];
	[[panel reenableFlushWindow] flushWindow];
	NXPing();
	[quit setTransparent:NO];
	[s play:self];
	[quit display];
	NXPing();
	[self sendReceipt];
    }
    [NXApp stopModal];
    [colorbars stopIt];
    [colorbars setDrawstyle:WINKOFF];
    [panel orderOut:sender];
    return self;
}

- quit:sender {
    [colorbars stopIt];
    [colorbars setDrawstyle:WINKOFF];
    exit(0);
}

@end
